package handlers

import (
	"fmt"
	"github.com/emicklei/go-restful"
	"io/ioutil"
	"mime/multipart"
	"kubeInstall/conf"
	"kubeInstall/model"
	"kubeInstall/utils"
	"net/http"
	"path/filepath"
)

func UploadPkg(r *restful.Request, w *restful.Response) {
	maxUploadSize := conf.AppSetting.MaxUploadSize
	if err := r.Request.ParseMultipartForm(maxUploadSize); err != nil {
		RenderError(w, fmt.Sprintf("Could not parse multipart form: %v\n", err), http.StatusInternalServerError)
		return
	}

	// 获取文件
	file, fileHeader, err := r.Request.FormFile("uploadFile")
	if err != nil {
		RenderError(w, fmt.Sprintf("Read Form from http failed! error is : %v\n", err), http.StatusBadRequest)
		return
	}
	defer file.Close()

	fileSize := fileHeader.Size
	// 检查上传文件大小
	if fileSize > maxUploadSize {
		RenderError(w, fmt.Sprintf("File size over max upload limit. size is %d ,limit is %d\n", fileSize, maxUploadSize), http.StatusBadRequest)
		return
	}

	// 检查上传文件类型
	fileType := fileHeader.Header.Get("Content-Type")
	//detectedFileType := http.DetectContentType(fileBytes)

	switch fileType {
	// docker images
	case "application/x-tar":
		HandleDockerImages(fileHeader, file, w)
	// rpm pkg,binary file
	case "application/x-redhat-package-manager", "application/octet-stream":
		HandleSysPackage(fileHeader, file, w)

	default:
		RenderError(w, fmt.Sprintf("File type not support,only support .tar or .rpm file"), http.StatusBadRequest)
		return
	}

}

func HandleSysPackage(fileHeader *multipart.FileHeader, file multipart.File, resp *restful.Response) {

	//检查文件是否存在
	//todo 检查文件内容。例如rpm specs 文件信息。
	filePath := filepath.Join(conf.AppSetting.SysPackPath, fileHeader.Filename)
	if utils.Exists(filePath) {
		RenderError(resp, fmt.Sprintf("file already exist"), http.StatusBadRequest)
		return
	}
	//写入文件到磁盘
	fileBytes, _ := ioutil.ReadAll(file)

	if err := utils.WriteFile(filePath, fileBytes); err != nil {
		RenderError(resp, fmt.Sprintf("Write to disk failed, error is : %v\n", err), http.StatusInternalServerError)
		return
	}

	//记录文件信息到数据库
	var pkg model.SysPackage
	pkg.Name = fileHeader.Filename
	pkg.Size = fileHeader.Size / 1024

	data, err := pkg.Create()

	if err != nil {
		utils.RemoveFile(filePath)
		RenderError(resp, fmt.Sprintf("record file info failed %v\n", err), http.StatusInternalServerError)
		return
	}
	// http返回
	resp.WriteHeaderAndJson(http.StatusOK, data, restful.MIME_JSON)

}

func HandleDockerImages(fileHeader *multipart.FileHeader, file multipart.File, resp *restful.Response) {

	//检查文件是否存在
	//todo 检查文件内容。例如manifest 文件信息。
	filePath := filepath.Join(conf.AppSetting.DockerImagesPath, fileHeader.Filename)
	if utils.Exists(filePath) {
		RenderError(resp, fmt.Sprintf("file already exist"), http.StatusBadRequest)
		return
	}
	//写入文件到磁盘
	fileBytes, _ := ioutil.ReadAll(file)
	if err := utils.WriteFile(filePath, fileBytes); err != nil {
		RenderError(resp, fmt.Sprintf("Write to disk failed, error is : %v\n", err), http.StatusInternalServerError)
		return
	}

	//记录文件信息到数据库
	var img model.DockerImage
	img.Name = fileHeader.Filename
	img.Size = fileHeader.Size / 1024

	data, err := img.Create()

	if err != nil {
		utils.RemoveFile(filePath)
		RenderError(resp, fmt.Sprintf("record docker images info failed %v\n", err), http.StatusInternalServerError)
		return
	}
	// http返回
	resp.WriteHeaderAndJson(http.StatusOK, data, restful.MIME_JSON)
}

func GetSysPkg(r *restful.Request, resp *restful.Response) {
	// list all sys packages
	var pkg model.SysPackage

	data, err := pkg.GetSysPackages()

	if err != nil {

		RenderError(resp, fmt.Sprintf("get sys packages failed! error is:  %v\n", err), http.StatusBadRequest)
		return
	}

	resp.WriteHeaderAndJson(http.StatusOK, data, restful.MIME_JSON)

}

func GetImages(r *restful.Request, resp *restful.Response) {
	// list all docker images
	var imgs model.DockerImage

	data, err := imgs.GetDockerImages()

	if err != nil {
		RenderError(resp, fmt.Sprintf("get docker images failed! error is:  %v\n", err), http.StatusBadRequest)
		return
	}

	resp.WriteHeaderAndJson(http.StatusOK, data, restful.MIME_JSON)
}
